/**
 @file ctc_port_cli.c

 @author  Copyright (C) 2011 Centec Networks Inc.  All rights reserved.

 @date 2009-11-14

 @version v2.0

 The file apply clis of port module
*/

#include "ctc_api.h"
#include "ctcs_api.h"
#include "ctc_cli.h"
#include "ctc_cli_common.h"
#include "ctc_debug.h"
#include "ctc_flexe_cli.h"

CTC_CLI(ctc_cli_flexe_debug_on,
        ctc_cli_flexe_debug_on_cmd,
        "debug flexe (ctc|sys) (debug-level {func|param|info|error} |)",
        CTC_CLI_DEBUG_STR,
        CTC_CLI_FLEXE_M_STR,
        "CTC Layer",
        "SYS Layer",
        CTC_CLI_DEBUG_LEVEL_STR,
        CTC_CLI_DEBUG_LEVEL_FUNC,
        CTC_CLI_DEBUG_LEVEL_PARAM,
        CTC_CLI_DEBUG_LEVEL_INFO,
        CTC_CLI_DEBUG_LEVEL_ERROR)
{
    uint32 typeenum = 0;
    uint8 level = CTC_DEBUG_LEVEL_INFO;
    uint8 index = 0;

    index = CTC_CLI_GET_ARGC_INDEX("debug-level");
    if (index != 0xFF)
    {
        level = CTC_DEBUG_LEVEL_NONE;
        index = CTC_CLI_GET_ARGC_INDEX("func");
        if (index != 0xFF)
        {
            level |= CTC_DEBUG_LEVEL_FUNC;
        }

        index = CTC_CLI_GET_ARGC_INDEX("param");
        if (index != 0xFF)
        {
            level |= CTC_DEBUG_LEVEL_PARAM;
        }

        index = CTC_CLI_GET_ARGC_INDEX("info");
        if (index != 0xFF)
        {
            level |= CTC_DEBUG_LEVEL_INFO;
        }

        index = CTC_CLI_GET_ARGC_INDEX("error");
        if (index != 0xFF)
        {
            level |= CTC_DEBUG_LEVEL_ERROR;
        }
    }

    if (0 == sal_memcmp(argv[0], "ctc", 3))
    {
        typeenum = FLEXE_CTC;
    }
    else
    {
        typeenum = FLEXE_SYS;
    }

    ctc_debug_set_flag("flexe", "flexe", typeenum, level, TRUE);


    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_flexe_debug_off,
        ctc_cli_flexe_debug_off_cmd,
        "no debug flexe (ctc|sys)",
        CTC_CLI_NO_STR,
        CTC_CLI_DEBUG_STR,
        CTC_CLI_FLEXE_M_STR,
        "CTC Layer",
        "SYS Layer")
{
    uint32 typeenum = 0;
    uint8 level = 0;

    if (0 == sal_memcmp(argv[0], "ctc", 3))
    {
        typeenum = FLEXE_CTC;
    }
    else
    {
        typeenum = FLEXE_SYS;
    }
    ctc_debug_set_flag("flexe", "flexe", typeenum, level, FALSE);

    return CLI_SUCCESS;
}


CTC_CLI(ctc_cli_flexe_set_en,
        ctc_cli_flexe_set_en_cmd,
        "flexe serdes SERDES_ID flexe-en (enable | disable)",
        CTC_CLI_FLEXE_M_STR,
        "SerDes",
        "SerDes id",
        "Flexe property",
        CTC_CLI_ENABLE,
        CTC_CLI_DISABLE)
{
    int32 ret = 0;
    uint16 serdes_id = 0;

    CTC_CLI_GET_UINT16("serdes", serdes_id, argv[0]);

    if (0 == sal_memcmp("en", argv[1], 2))
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_set_en(g_api_ldev, serdes_id, TRUE);
        }
        else
        {
            ret = ctc_flexe_set_en(g_api_ldev, serdes_id, TRUE);
        }
    }
    else if (0 == sal_memcmp("di", argv[1], 2))
    {
        if(g_ctcs_api_en)
        {
             ret = ctcs_flexe_set_en(g_api_ldev, serdes_id, FALSE);
        }
        else
        {
            ret = ctc_flexe_set_en(g_api_ldev, serdes_id, FALSE);
        }
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_get_en,
        ctc_cli_flexe_get_en_cmd,
        "show flexe serdes SERDES_ID flexe-en",
        "Show operate",
        CTC_CLI_FLEXE_M_STR,
        "SerDes",
        "SerDes id",
        "Flexe enable config")
{
    int32 ret = 0;
    uint16 serdes_id = 0;
    uint8 value = 0;

    CTC_CLI_GET_UINT16("serdes", serdes_id, argv[0]);

    ctc_cli_out("Show SerDes                        :  %d\n", serdes_id);
    ctc_cli_out("-------------------------------------------\n");

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_get_en(g_api_ldev, serdes_id, &value);
    }
    else
    {
        ret = ctc_flexe_get_en(g_api_ldev, serdes_id, &value);
    }

    if (ret >= 0)
    {
        ctc_cli_out("%-34s:", "FlexE-en");
        ctc_cli_out("  %d\n", value);
    }
    ctc_cli_out("------------------------------------------\n");

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_create_group,
        ctc_cli_flexe_create_group_cmd,
        "flexe create group GROUP_ID group-number GROUP_NUM (switch-mode MODE |)",
        CTC_CLI_FLEXE_M_STR,
        "Create operate",
        "FlexE group",
        "Group id",
        "FlexE group number",
        "FlexE group number value",
        "FlexE group switch mode",
        "FlexE group switch mode: 0 -- dynamic; 1 -- manual")
{
    int32 ret = 0;
    uint8 index = 0;
    uint32 group_id = 0;
    uint32 group_number = 0;
    uint8  group_switch_flag = 0;
    ctc_flexe_grp_t group;

    sal_memset(&group, 0, sizeof(ctc_flexe_grp_t));

    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);
    CTC_CLI_GET_UINT32("group_number", group_number, argv[1]);

    group.group_num = group_number;
    index = CTC_CLI_GET_ARGC_INDEX("switch-mode");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT32("switch-mode", group_switch_flag, argv[index+1]);
        group.flag = group_switch_flag;
    }

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_create_group(g_api_ldev, group_id, &group);
    }
    else
    {
        ret = ctc_flexe_create_group(g_api_ldev, group_id, &group);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_destroy_group,
        ctc_cli_flexe_destroy_group_cmd,
        "flexe destroy group GROUP_ID",
        CTC_CLI_FLEXE_M_STR,
        "Destroy operate",
        "FlexE group",
        "Group id")
{
    int32 ret = 0;
    uint32 group_id = 0;

    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_destroy_group(g_api_ldev, group_id);
    }
    else
    {
        ret = ctc_flexe_destroy_group(g_api_ldev, group_id);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_set_group_number,
        ctc_cli_flexe_set_group_number_cmd,
        "flexe group GROUP_ID property group-number GROUP_NUM",
        CTC_CLI_FLEXE_M_STR,
        "FlexE group",
        "Group id",
        "FlexE property",
        "FlexE group number",
        "FlexE group number value")
{
    int32 ret = 0;
    uint32 group_id = 0;
    uint32 group_number = 0;

    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);
    CTC_CLI_GET_UINT32("group_number", group_number, argv[1]);
    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_GRP_NUM, (void*)&group_number);
    }
    else
    {
        ret = ctc_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_GRP_NUM, (void*)&group_number);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_set_group_calendar,
        ctc_cli_flexe_set_group_calendar_cmd,
        "flexe group GROUP_ID property cal-sel SEL",
        CTC_CLI_FLEXE_M_STR,
        "FlexE group",
        "Group id",
        "FlexE property",
        "FlexE calendar select",
        "0:calendar A, 1:calendar B")
{
    int32 ret = 0;
    uint32 group_id = 0;
    uint32 calendar_sel = 0;

    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);
    CTC_CLI_GET_UINT32("calendar sel", calendar_sel, argv[1]);
    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_CAL_SEL, (void*)&calendar_sel);
    }
    else
    {
        ret = ctc_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_CAL_SEL, (void*)&calendar_sel);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}
CTC_CLI(ctc_cli_flexe_group_set_phylist,
        ctc_cli_flexe_group_set_phylist_cmd,
        "flexe group GROUP_ID property phy-list [VAL]",
        CTC_CLI_FLEXE_M_STR,
        "FlexE group",
        "Group id",
        "Property",
        "PHY list",
        "PHY list value")
{
    int32 ret = 0;
    uint32 group_id = 0;
    uint32  phy_cnt = 0;
    ctc_flexe_phy_t phy;

    sal_memset(&phy, 0, sizeof(ctc_flexe_phy_t));

    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);
    phy_cnt = CTC_CLI_STR_ARRAY_NUM(argv[1]);
    if (phy_cnt)
    {
        phy.serdes_id = mem_malloc(MEM_CLI_MODULE, phy_cnt * sizeof(uint16));
        if (NULL == phy.serdes_id)
        {
            ctc_cli_out("!!!! value_array alloc failed!\n");
            return CLI_ERROR;
        }
        CTC_CLI_GET_UINT16_ARRAY(argv[1], phy.serdes_id, &phy_cnt, argv[1], ret);
    }
    phy.serdes_cnt = phy_cnt;

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_PHY, (void*)&phy);
    }
    else
    {
        ret = ctc_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_PHY, (void*)&phy);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_group_set_switch_mode,
        ctc_cli_flexe_group_set_switch_mode_cmd,
        "flexe group GROUP_ID property switch-mode VAL",
        CTC_CLI_FLEXE_M_STR,
        "FlexE group",
        "Group id",
        "Property",
        "FlexE group switch mode",
        "FlexE group switch mode: 0 -- dynamic; 1 -- manual")
{
    int32 ret = 0;
    uint32 group_id = 0;
    uint32 switch_mode = 0;

    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);
    CTC_CLI_GET_UINT32("switch-mode", switch_mode, argv[1]);

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_SWITCH_MODE, (void*)&switch_mode);
    }
    else
    {
        ret = ctc_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_SWITCH_MODE, (void*)&switch_mode);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return ret;
}
CTC_CLI(ctc_cli_flexe_group_set_switch,
        ctc_cli_flexe_group_set_switch_cmd,
        "flexe group GROUP_ID property cr-switch VALUE",
        CTC_CLI_FLEXE_M_STR,
        "FlexE group",
        "Group id",
        "Property",
        "CR switch",
        "Switch value")
{
    int32 ret = 0;
    uint32 group_id = 0;
    uint32 val32 = 0;
    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);
    CTC_CLI_GET_UINT32("value", val32, argv[1]);
    //CTC_CLI_GET_UINT32("value", value, argv[2]);

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_SWITCH_TRIGGER, (void*)&val32);
    }
    else
    {
        ret = ctc_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_SWITCH_TRIGGER, (void*)&val32);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_set_phy_number,
        ctc_cli_flexe_set_phy_number_cmd,
        "flexe phy PHY_ID property phy-number PHY_NUM",
        CTC_CLI_FLEXE_M_STR,
        "FlexE phy",
        "SerDes id",
        "FlexE property",
        "FlexE phy number",
        "FlexE phy number value")
{
    int32 ret = 0;
    uint16 serdes_id = 0;
    uint32 phy_number = 0;

    CTC_CLI_GET_UINT16("phy_id", serdes_id, argv[0]);
    CTC_CLI_GET_UINT32("phy_number", phy_number, argv[1]);
    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_phy_property(g_api_ldev, serdes_id, CTC_FLEXE_PHY_PROP_PHY_NUM, (void*)&phy_number);
    }
    else
    {
        ret = ctc_flexe_set_phy_property(g_api_ldev, serdes_id, CTC_FLEXE_PHY_PROP_PHY_NUM, (void*)&phy_number);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_get_group,
        ctc_cli_flexe_get_group_cmd,
        "show flexe group GROUP_ID",
        "Show operate",
        CTC_CLI_FLEXE_M_STR,
        "FlexE group",
        "Group id")
{
    int32 ret = 0;
    uint32 group_id = 0;
    uint8  i   = 0;
    uint16 serdes_id[16] = {0};
    ctc_flexe_grp_t group;

    sal_memset(&group, 0, sizeof(ctc_flexe_grp_t));
    group.phy.serdes_id = serdes_id;

    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_get_group(g_api_ldev, group_id, &group);
    }
    else
    {
        ret = ctc_flexe_get_group(g_api_ldev, group_id, &group);
    }

    ctc_cli_out("%-45s:  0x%04x\n","FlexE Group", group_id);
    ctc_cli_out("--------------------------------------------------------\n");

    if (ret >= 0)
    {
        ctc_cli_out("%-45s:  %d\n", "group_number", group.group_num);
        ctc_cli_out("%-45s:  %d\n", "phy_cnt", group.phy.serdes_cnt);
        ctc_cli_out("%-45s:  ", "phy_list");
        for (i = 0; i < group.phy.serdes_cnt; i++)
        {
            ctc_cli_out("%d ", group.phy.serdes_id[i]);
        }
        ctc_cli_out("\n");
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_add_client,
        ctc_cli_flexe_add_client_cmd,
        "flexe add client CLIENT_ID",
        CTC_CLI_FLEXE_M_STR,
        CTC_CLI_ADD,
        "FlexE client",
        "Client id")
{
    int32 ret = 0;
    uint32 client_id = 0;

    CTC_CLI_GET_UINT32("client_id", client_id, argv[0]);
    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_add_client(g_api_ldev, client_id, NULL);
    }
    else
    {
        ret = ctc_flexe_add_client(g_api_ldev, client_id, NULL);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_remove_client,
        ctc_cli_flexe_remove_client_cmd,
        "flexe remove client CLIENT_ID",
        CTC_CLI_FLEXE_M_STR,
        CTC_CLI_REMOVE,
        "FlexE client",
        "Client id")
{
    int32 ret = 0;
    uint32 client_id = 0;

    CTC_CLI_GET_UINT32("client_id", client_id, argv[0]);
    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_remove_client(g_api_ldev, client_id);
    }
    else
    {
        ret = ctc_flexe_remove_client(g_api_ldev, client_id);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_get_client,
        ctc_cli_flexe_get_client_cmd,
        "show flexe client CLIENT_ID",
        "Show operate",
        CTC_CLI_FLEXE_M_STR,
        "FlexE client",
        "Client id")
{
    int32  ret = CLI_SUCCESS;
    uint8  i   = 0;
    uint8  j   = 0;
    uint32 client_id = 0;
    uint8  client_slot_exist = 0;
    ctc_flexe_client_t client;

    CTC_CLI_GET_UINT32("client_id", client_id, argv[0]);
    client.slot.slot = mem_malloc(MEM_CLI_MODULE, 8 * sizeof(ctc_flexe_slot_bmp_t));
    if (NULL == client.slot.slot)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(client.slot.slot, 0, 8 * sizeof(ctc_flexe_slot_bmp_t));

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_get_client(g_api_ldev, client_id, &client);
    }
    else
    {
        ret = ctc_flexe_get_client(g_api_ldev, client_id, &client);
    }

    ctc_cli_out("%-45s:  0x%04x\n","FlexE Client", client_id);
    ctc_cli_out("--------------------------------------------------------\n");

    if (ret >= 0)
    {
        if(0xffffffff == client.group_id)
        {
            ctc_cli_out("%-45s:  Not Set\n", "group_id");
        }
        else
        {
            ctc_cli_out("%-45s:  %d\n", "group_id", client.group_id);
        }

        if(0 == client.client_num)
        {
            ctc_cli_out("%-45s:  Not Set\n", "client_number");
        }
        else
        {
            ctc_cli_out("%-45s:  %d\n", "client_number", client.client_num);
        }
        for (i = 0; i < client.slot.phy_cnt; i++)
        {
            for (j = 0; j < 80; j++)
            {
                if (CTC_BMP_ISSET(client.slot.slot[i].slot_bmp, j))
                {
                    client_slot_exist = 1;
                    break;
                }
            }
            if (1 == client_slot_exist)
            {
                break;
            }
        }
        if(0xffffffff == client.group_id || 0 == client_slot_exist)
        {
            ctc_cli_out("%-45s:  Not Set\n", "client_slot");
        }
        else
        {
            ctc_cli_out("%-45s:  \n", "client_slot");
            for (i = 0; i < client.slot.phy_cnt; i++)
            {
                ctc_cli_out("%51s %d:\t", "phy", client.slot.slot[i].serdes_id);
                for (j = 0; j < 80; j++)
                {
                    if (CTC_BMP_ISSET(client.slot.slot[i].slot_bmp, j))
                    {
                        ctc_cli_out("%2d ", j);
                    }
                }
                ctc_cli_out("\n");
            }
        }
    }
    mem_free(client.slot.slot);
    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}


CTC_CLI(ctc_cli_flexe_set_client_groupid,
        ctc_cli_flexe_set_client_groupid_cmd,
        "flexe client CLIENT_ID property group GROUP_ID",
        CTC_CLI_FLEXE_M_STR,
        "FlexE client",
        "Client id",
        "FlexE property",
        "FlexE group",
        "FlexE group ID value")
{
    int32 ret = 0;
    uint32 client_id = 0;
    uint32 group_id = 0;

    CTC_CLI_GET_UINT32("client id", client_id, argv[0]);
    CTC_CLI_GET_UINT32("group id", group_id, argv[1]);
    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_GROUP_ID, (void*)&group_id);
    }
    else
    {
        ret = ctc_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_GROUP_ID, (void*)&group_id);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}


CTC_CLI(ctc_cli_flexe_set_client_number,
        ctc_cli_flexe_set_client_number_cmd,
        "flexe client CLIENT_ID property client-number CLIENT_NUM",
        CTC_CLI_FLEXE_M_STR,
        "FlexE client",
        "Client id",
        "FlexE property",
        "FlexE client number",
        "FlexE client number value")
{
    int32 ret = 0;
    uint32 client_id = 0;
    uint32 client_number = 0;

    CTC_CLI_GET_UINT32("client id", client_id, argv[0]);
    CTC_CLI_GET_UINT32("client number", client_number, argv[1]);

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_CLIENT_NUM, (void*)&client_number);
    }
    else
    {
        ret = ctc_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_CLIENT_NUM, (void*)&client_number);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_set_client_port,
        ctc_cli_flexe_set_client_port_cmd,
        "flexe client CLIENT_ID property port VALUE",
        CTC_CLI_FLEXE_M_STR,
        "FlexE client",
        "Client id",
        "FlexE property",
        "Global Phy Port",
        "Value")
{
    int32 ret = 0;
    uint32 client_id = 0;
    uint32 gport = 0;

    CTC_CLI_GET_UINT32("client id", client_id, argv[0]);
    CTC_CLI_GET_UINT32("gport", gport, argv[1]);

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_BINDING_PORT, (void*)&gport);
    }
    else
    {
        ret = ctc_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_BINDING_PORT, (void*)&gport);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_set_client_rxtx,
        ctc_cli_flexe_set_client_rxtx_cmd,
        "flexe client CLIENT_ID property rx VALUE tx VALUE",
        CTC_CLI_FLEXE_M_STR,
        "FlexE client",
        "Client id",
        "FlexE property",
        "Rx property",
        "Value",
        "Tx property",
        "Value")
{
    int32 ret = 0;
    uint32 client_id = 0;
    uint32 rxtx_en = 0;
    uint8 rx_en = 0;
    uint8 tx_en = 0;

    CTC_CLI_GET_UINT32("client id", client_id, argv[0]);
    CTC_CLI_GET_UINT8("rx_en", rx_en, argv[1]);
    CTC_CLI_GET_UINT8("tx_en", tx_en, argv[2]);

    rxtx_en = ((tx_en) | (rx_en <<1));

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_TX_RX, (void*)&rxtx_en);
    }
    else
    {
        ret = ctc_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_TX_RX, (void*)&rxtx_en);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_set_client_prop,
        ctc_cli_flexe_set_client_prop_cmd,
        "flexe client CLIENT_ID property mac-en EN",
        CTC_CLI_FLEXE_M_STR,
        "FlexE client",
        "Client id",
        "FlexE property",
        "Mac-en property",
        "Value")
{
    int32 ret = 0;
    uint32 client_id = 0;
    uint32 mac_en = 0;

    CTC_CLI_GET_UINT32("client id", client_id, argv[0]);
    CTC_CLI_GET_UINT32("mac en", mac_en, argv[1]);

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_MAC_EN, (void*)&mac_en);
    }
    else
    {
        ret = ctc_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_MAC_EN, (void*)&mac_en);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_set_client_unport,
        ctc_cli_flexe_set_client_unport_cmd,
        "flexe client CLIENT_ID property unbind port",
        CTC_CLI_FLEXE_M_STR,
        "FlexE client",
        "Client id",
        "Value of client id",
        "FlexE property",
        "Unbind port")
{
    int32 ret = 0;
    uint32 client_id = 0;
    uint32 gport = 0xFFFFFFFF;

    CTC_CLI_GET_UINT32("client id", client_id, argv[0]);

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_BINDING_PORT, (void*)&gport);
    }
    else
    {
        ret = ctc_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_BINDING_PORT, (void*)&gport);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_set_client_rx_recover,
        ctc_cli_flexe_set_client_rx_recover_cmd,
        "flexe client CLIENT_ID property rx-recover VALUE",
        CTC_CLI_FLEXE_M_STR,
        "FlexE client",
        "Client id",
        "FlexE property",
        "Rx-recover property",
        "Value")
{
    int32 ret = 0;
    uint32 client_id = 0;
    uint32 value = 0;

    CTC_CLI_GET_UINT32("client id", client_id, argv[0]);
    CTC_CLI_GET_UINT32("rx-recover", value, argv[1]);

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_RX_RECOVER, (void*)&value);
    }
    else
    {
        ret = ctc_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_RX_RECOVER, (void*)&value);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_show_flexe_group_property,
        ctc_cli_show_flexe_group_property_cmd,
        "show flexe group GROUP_ID property (all|group-number|phy|switch-mode|cal-sel|cr-timer|sync-msg | pad)",
        "Show operate",
        CTC_CLI_FLEXE_M_STR,
        "FlexE group",
        "Group id",
        "Property",
        "Show all property",
        "Group_number",
        "Phy",
        "Switch mode",
        "Calendar select",
        "Cr timer",
        "Synchronization messaging channel",
        "Pading")
{
    int32 ret = 0;
    uint16 serdes_idx = 0;
    uint32 group_id = 0;
    uint8 index = 0;
    uint8 show_all = 0;
    uint32 value = FALSE;
    ctc_flexe_phy_t p_phy_value;

    index = CTC_CLI_GET_ARGC_INDEX("all");
    if (index != 0xFF)
    {
        show_all = 1;
    }

    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);
    ctc_cli_out("Show group_id                        :  0x%04x\n", group_id);
    ctc_cli_out("-------------------------------------------\n");

    index = CTC_CLI_GET_ARGC_INDEX("group-number");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_GRP_NUM, &value);
        }
        else
        {
            ret = ctc_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_GRP_NUM, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "group-number", value);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("phy");
    if ((index != 0xFF) || show_all)
    {
        p_phy_value.serdes_id = (uint16*)mem_malloc(MEM_DMPS_MODULE, sizeof(uint16) * 8);
        if (NULL == p_phy_value.serdes_id)
        {
            return CTC_E_NO_MEMORY;
        }
        sal_memset(p_phy_value.serdes_id, 0, 8 * sizeof(uint16));

        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_PHY, (void*)&p_phy_value);
        }
        else
        {
            ret = ctc_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_PHY, (void*)&p_phy_value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %d\n", "phy serdes_cnt", p_phy_value.serdes_cnt);
            ctc_cli_out("%-34s:  ", "phy serdes_id");
            for(serdes_idx = 0; serdes_idx < p_phy_value.serdes_cnt; serdes_idx++)
            {
                ctc_cli_out("%2d ", p_phy_value.serdes_id[serdes_idx]);
            }
            ctc_cli_out("\n");
        }
        mem_free(p_phy_value.serdes_id);
    }

    index = CTC_CLI_GET_ARGC_INDEX("switch-mode");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_SWITCH_MODE, &value);
        }
        else
        {
            ret = ctc_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_SWITCH_MODE, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "switch-mode", value);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("cal-sel");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_CAL_SEL, &value);
        }
        else
        {
            ret = ctc_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_CAL_SEL, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "calendar-select", value);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("cr-timer");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_CR_TIMER, &value);
        }
        else
        {
            ret = ctc_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_CR_TIMER, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "cr-timer", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("sync-msg");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_SYNC_MSG_EN, &value);
        }
        else
        {
            ret = ctc_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_SYNC_MSG_EN, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "sync-msg", value);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX("pad");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_PAD_EN, &value);
        }
        else
        {
            ret = ctc_flexe_get_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_PAD_EN, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "pad", value);
        }
    }
    ctc_cli_out("------------------------------------------\n");

    if ((ret < 0) && (!show_all))
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_show_flexe_client_property,
        ctc_cli_show_flexe_client_property_cmd,
        "show flexe client CLIENT_ID property (all|group_id|client_number|gport|slot|tx_rx|hw_client|speed|mac-en|link-up|)",
        "Show operate",
        CTC_CLI_FLEXE_M_STR,
        "FlexE client",
        "Client id",
        "Property",
        "Show all property",
        "Show group property",
        "Client_number",
        "Gport",
        "Slot",
        "Tx_rx",
        "Hw client",
        "Speed",
        "Mac Enable",
        "Link status")
{
    uint8 i = 0, j = 0;
    int32 ret = 0;
    uint32 client_id = 0;
    uint8 index = 0;
    uint8 show_all = 0;
    uint32 value = FALSE;
    ctc_flexe_client_slot_t  p_flexe_slot;

    index = CTC_CLI_GET_ARGC_INDEX("all");
    if (index != 0xFF)
    {
        show_all = 1;
    }

    CTC_CLI_GET_UINT32("client_id", client_id, argv[0]);
    ctc_cli_out("Show client_id                        :  0x%04x\n", client_id);
    ctc_cli_out("-------------------------------------------\n");

    index = CTC_CLI_GET_ARGC_INDEX("group_id");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_GRP_PROP_GRP_NUM, &value);
        }
        else
        {
            ret = ctc_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_GRP_PROP_GRP_NUM, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "group_id", value);
        }
    }
    value = 0;
    index = CTC_CLI_GET_ARGC_INDEX("client_number");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_CLIENT_NUM, &value);
        }
        else
        {
            ret = ctc_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_CLIENT_NUM, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "client_number", value);
        }
    }
    value = 0;
    index = CTC_CLI_GET_ARGC_INDEX("gport");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_BINDING_PORT, &value);
        }
        else
        {
            ret = ctc_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_BINDING_PORT, &value);
        }
        if (ret >= 0)
        {
            if (0xffffffff == value)
            {
                ctc_cli_out("%-34s:  %s\n", "gport", "Not config");
            }
            else
            {
                ctc_cli_out("%-34s:  %u\n", "gport", value);
            }
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("slot");
    if ((index != 0xFF) || show_all)
    {
        p_flexe_slot.slot = (ctc_flexe_slot_bmp_t*)mem_malloc(MEM_DMPS_MODULE, sizeof(ctc_flexe_slot_bmp_t) * 8);
        if (NULL == p_flexe_slot.slot)
        {
            return CTC_E_NO_MEMORY;
        }
        sal_memset(p_flexe_slot.slot, 0, 8 * sizeof(ctc_flexe_slot_bmp_t));

        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_SLOT, &p_flexe_slot);
        }
        else
        {
            ret = ctc_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_SLOT, &p_flexe_slot);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "phy cnt", p_flexe_slot.phy_cnt);
            ctc_cli_out("%-34s:  \n", "client slot");
            for(i = 0; i < p_flexe_slot.phy_cnt; i++)
            {
                ctc_cli_out("%40s %u :", "phy", p_flexe_slot.slot[i].serdes_id);
                for (j = 0; j < 80; j++)
                {
                    if (CTC_BMP_ISSET(p_flexe_slot.slot[i].slot_bmp, j))
                    {
                        ctc_cli_out("%2u ", j);
                    }
                }
                ctc_cli_out("\n");
            }
        }
        mem_free(p_flexe_slot.slot);
    }
    value = 0;
    index = CTC_CLI_GET_ARGC_INDEX("tx_rx");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_TX_RX, &value);
        }
        else
        {
            ret = ctc_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_TX_RX, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "rx", (value&0x1)?1:0);
            ctc_cli_out("%-34s:  %u\n", "tx", (value&0x2)?1:0);
        }
    }

    value = 0;
    index = CTC_CLI_GET_ARGC_INDEX("speed");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_SPEED, &value);
        }
        else
        {
            ret = ctc_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_SPEED, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %uG\n", "work speed", (value*5));
        }
    }

    value = 0;
    index = CTC_CLI_GET_ARGC_INDEX("mac-en");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_MAC_EN, &value);
        }
        else
        {
            ret = ctc_flexe_get_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_MAC_EN, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "mac-en", value);
        }
    }

    value = 0;
    index = CTC_CLI_GET_ARGC_INDEX("link-up");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_client_link_up(g_api_ldev, client_id, (bool*)&value);
        }
        else
        {
            ret = ctc_flexe_get_client_link_up(g_api_ldev, client_id, (bool*)&value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "link-up", value);
        }
    }
    ctc_cli_out("------------------------------------------\n");

    if ((ret < 0) && (!show_all))
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_show_flexe_phy_property,
        ctc_cli_show_flexe_phy_property_cmd,
        "show flexe phy SERDES_ID property (all|phy-number|slot|crc-cnt|)",
        "Show operate",
        CTC_CLI_FLEXE_M_STR,
        "FlexE phy",
        "Serdes id",
        "Property",
        "Show all property",
        "Phy_number",
        "Slot",
        "Crc count")
{
    uint8 i = 0;
    int32 ret = 0;
    uint32 serdes_id = 0;
    uint8 index = 0;
    uint8 show_all = 0;
    uint32 value = FALSE;
    ctc_flexe_phy_timeslot_t  p_flexe_timeslot;

    index = CTC_CLI_GET_ARGC_INDEX("all");
    if (index != 0xFF)
    {
        show_all = 1;
    }

    CTC_CLI_GET_UINT32("serdes_id", serdes_id, argv[0]);
    ctc_cli_out("Show serdes_id                        :  0x%04x\n", serdes_id);
    ctc_cli_out("-------------------------------------------\n");

    index = CTC_CLI_GET_ARGC_INDEX("phy-number");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_phy_property(g_api_ldev, serdes_id, CTC_FLEXE_PHY_PROP_PHY_NUM, &value);
        }
        else
        {
            ret = ctc_flexe_get_phy_property(g_api_ldev, serdes_id, CTC_FLEXE_PHY_PROP_PHY_NUM, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "phy_number", value);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("slot");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_phy_property(g_api_ldev, serdes_id, CTC_FLEXE_PHY_PROP_SLOT, &p_flexe_timeslot);
        }
        else
        {
            ret = ctc_flexe_get_phy_property(g_api_ldev, serdes_id, CTC_FLEXE_PHY_PROP_SLOT, &p_flexe_timeslot);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %d\n", "serdes_id", p_flexe_timeslot.serdes_id);
            ctc_cli_out("%-34s:  %d\n", "slot_num", p_flexe_timeslot.slot_num);
            ctc_cli_out("%-34s:  \n", "client id");
            for (i = 0; i < 80; i++)
            {
                if (p_flexe_timeslot.client_id[i])
                {
                    ctc_cli_out("%41s :%d  client id :%u\n", "slot", i, p_flexe_timeslot.client_id[i]);
                }
            }
        }
    }


    index = CTC_CLI_GET_ARGC_INDEX("crc-cnt");
    if ((index != 0xFF) || show_all)
    {
        if(g_ctcs_api_en)
        {
            ret = ctcs_flexe_get_phy_property(g_api_ldev, serdes_id, CTC_FLEXE_PHY_PROP_CRC_CNT, &value);
        }
        else
        {
            ret = ctc_flexe_get_phy_property(g_api_ldev, serdes_id, CTC_FLEXE_PHY_PROP_CRC_CNT, &value);
        }
        if (ret >= 0)
        {
            ctc_cli_out("%-34s:  %u\n", "crc_cnt", value);
        }
    }

    ctc_cli_out("------------------------------------------\n");

    if ((ret < 0) && (!show_all))
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}


CTC_CLI(ctc_cli_show_flexe_group_oh,
        ctc_cli_show_flexe_group_oh_cmd,
        "show flexe phy oh-info SERDES_ID instance OFFSET dir DIR",
        "Show operate",
        CTC_CLI_FLEXE_M_STR,
        "FlexE phy",
        "OH ram information",
        "Serdes id",
        "Instance offset",
        "Offset value",
        "Direction",
        "0:rx,1:tx")
{
    int32 ret = 0;
    uint32 serdes_id = 0;
    ctc_flexe_phy_oh_t flexe_oh;
    uint8 index = 0;

    sal_memset(&flexe_oh, 0, sizeof(ctc_flexe_phy_oh_t));

    CTC_CLI_GET_UINT32("serdes_id", serdes_id, argv[0]);
    CTC_CLI_GET_UINT8("instance offset", flexe_oh.instance_offset, argv[1]);
    CTC_CLI_GET_UINT8("direction", flexe_oh.dir, argv[2]);

    ctc_cli_out("OH ram information: \n");
    ctc_cli_out("-------------------------------------------\n");

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_get_phy_property(g_api_ldev, serdes_id, CTC_FLEXE_PHY_PROP_OH_INFO, &flexe_oh);
    }
    else
    {
        ret = ctc_flexe_get_phy_property(g_api_ldev, serdes_id, CTC_FLEXE_PHY_PROP_OH_INFO, &flexe_oh);
    }
    if (ret >= 0)
    {
        ctc_cli_out("%-34s:  %d\n", "serdes_id", serdes_id);
        ctc_cli_out("%-34s:  %d\n", "instance_offset", flexe_oh.instance_offset);
        ctc_cli_out("%-34s:  %d\n", "group_num", flexe_oh.group_num);
        ctc_cli_out("%-34s:  %d\n", "instance_num", flexe_oh.instance_num);
        ctc_cli_out("%-34s:  %d\n", "dir", flexe_oh.dir);
        ctc_cli_out("%-34s:  0x%x\n", "flag", flexe_oh.flag);
        ctc_cli_out("-------------------------------------------\n");

        ctc_cli_out(" %-14s%-16s%-27s%-27s \n", "OH frame id", "FlexE Map(hex)", "Client Carried Calendar A", "Client Carried Calendar B");
        for (index = 0; index < 32; index++)
        {
            ctc_cli_out(" ");
            ctc_cli_out("%-14d", index);
            ctc_cli_out("%-16x", flexe_oh.flexe_map[index]);
            ctc_cli_out("%-16x", flexe_oh.client_bmp_a[index]);
            ctc_cli_out("%-16x", flexe_oh.client_bmp_b[index]);
            ctc_cli_out("\n");
        }
    }
    ctc_cli_out("------------------------------------------\n");

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

#define CTC_CLI_FLEXE_CLIENT_SLOTLIST_STR "phy PHY_ID slot [VAL] \
    (phy1 PHY_ID slot1 [VAL] |) (phy2 PHY_ID slot2 [VAL] |) (phy3 PHY_ID slot3 [VAL] |) \
    (phy4 PHY_ID slot4 [VAL] |) (phy5 PHY_ID slot5 [VAL] |) (phy6 PHY_ID slot6 [VAL] |) \
    (phy7 PHY_ID slot7 [VAL] |)"

#define CTC_CLI_FLEXE_CLIENT_SLOTLIST_DESC   \
    "FlexE PHY",                             \
    "FlexE PHY ID",                          \
    "Time slot",                             \
    "Time slot list value",                  \
    "FlexE PHY1",                            \
    "FlexE PHY1 ID",                         \
    "Time slot1",                            \
    "Time slot1 list value",                 \
    "FlexE PHY2",                            \
    "FlexE PHY2 ID",                         \
    "Time slot2",                            \
    "Time slot2 list value",                 \
    "FlexE PHY3",                            \
    "FlexE PHY3 ID",                         \
    "Time slot3",                            \
    "Time slot3 list value",                 \
    "FlexE PHY4",                            \
    "FlexE PHY4 ID",                         \
    "Time slot4",                            \
    "Time slot4 list value",                 \
    "FlexE PHY5",                            \
    "FlexE PHY5 ID",                         \
    "Time slot5",                            \
    "Time slot5 list value",                 \
    "FlexE PHY6",                            \
    "FlexE PHY6 ID",                         \
    "Time slot6",                            \
    "Time slot6 list value",                 \
    "FlexE PHY7",                            \
    "FlexE PHY7 ID",                         \
    "Time slot7",                            \
    "Time slot7 list value"

CTC_CLI(ctc_cli_flexe_client_bind_slot,
        ctc_cli_flexe_client_bind_slot_cmd,
        "flexe client CLIENT_ID property bind-slot "CTC_CLI_FLEXE_CLIENT_SLOTLIST_STR" (flag VALUE |)",
        CTC_CLI_FLEXE_M_STR,
        "FlexE client",
        "Client id",
        "Property",
        "Bind slot",
        CTC_CLI_FLEXE_CLIENT_SLOTLIST_DESC,
        "Flag, whether to modify slot forcibly",
        "Value, a bitmap, bit0:If set, indicate modify client slot force, bit1: rx direction, bit2: tx direction")
{
    int32 ret = 0;
    uint32 client_id = 0;
    uint32 slot_num[8]  = {0};
    uint8 slotlist[8][80] = {{0}};
    uint16 serdes_id[8] = {0};
    uint8  serdes_cnt = 0;
    uint8  index = 0;
    uint8  i = 0, j = 0, k = 0;
    ctc_flexe_client_slot_t client_slot;
    ctc_flexe_slot_bmp_t slot[8] = {{0}};

    sal_memset(&client_slot, 0, sizeof(ctc_flexe_client_slot_t));

    client_slot.slot = slot;

    CTC_CLI_GET_UINT32("client id", client_id, argv[0]);
    CTC_CLI_GET_UINT32("PHY id", serdes_id[0], argv[1]);
    serdes_cnt++;

    slot_num[0] = CTC_CLI_STR_ARRAY_NUM(argv[2]);
    if (0 != slot_num[0])
    {
        CTC_CLI_GET_UINT8_ARRAY(argv[2], slotlist[0], &slot_num[0], argv[2], ret);
    }

    index = CTC_CLI_GET_ARGC_INDEX("phy1");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("PHY id", serdes_id[1], argv[index+1]);
        serdes_cnt++;

        slot_num[1] = CTC_CLI_STR_ARRAY_NUM(argv[index+3]);
        if (0 != slot_num[1])
        {
            CTC_CLI_GET_UINT8_ARRAY(argv[index+3], slotlist[1], &slot_num[1], argv[index+3], ret);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("phy2");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("PHY id", serdes_id[2], argv[index+1]);
        serdes_cnt++;

        slot_num[2] = CTC_CLI_STR_ARRAY_NUM(argv[index+3]);
        if (0 != slot_num[2])
        {
            CTC_CLI_GET_UINT8_ARRAY(argv[index+3], slotlist[2], &slot_num[2], argv[index+3], ret);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("phy3");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("PHY id", serdes_id[3], argv[index+1]);
        serdes_cnt++;

        slot_num[3] = CTC_CLI_STR_ARRAY_NUM(argv[index+3]);
        if (0 != slot_num[3])
        {
            CTC_CLI_GET_UINT8_ARRAY(argv[index+3], slotlist[3], &slot_num[3], argv[index+3], ret);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("phy4");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("PHY id", serdes_id[4], argv[index+1]);
        serdes_cnt++;

        slot_num[4] = CTC_CLI_STR_ARRAY_NUM(argv[index+3]);
        if (0 != slot_num[4])
        {
            CTC_CLI_GET_UINT8_ARRAY(argv[index+3], slotlist[4], &slot_num[4], argv[index+3], ret);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("phy5");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("PHY id", serdes_id[5], argv[index+1]);
        serdes_cnt++;

        slot_num[5] = CTC_CLI_STR_ARRAY_NUM(argv[index+3]);
        if (0 != slot_num[5])
        {
            CTC_CLI_GET_UINT8_ARRAY(argv[index+3], slotlist[5], &slot_num[5], argv[index+3], ret);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("phy6");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("PHY id", serdes_id[6], argv[index+1]);
        serdes_cnt++;

        slot_num[6] = CTC_CLI_STR_ARRAY_NUM(argv[index+3]);
        if (0 != slot_num[6])
        {
            CTC_CLI_GET_UINT8_ARRAY(argv[index+3], slotlist[6], &slot_num[6], argv[index+3], ret);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("phy7");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("PHY id", serdes_id[7], argv[index+1]);
        serdes_cnt++;

        slot_num[7] = CTC_CLI_STR_ARRAY_NUM(argv[index+3]);
        if (0 != slot_num[7])
        {
            CTC_CLI_GET_UINT8_ARRAY(argv[index+3], slotlist[7], &slot_num[7], argv[index+3], ret);
        }
    }

    index = CTC_CLI_GET_ARGC_INDEX("flag");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT16("flag", client_slot.flag, argv[index + 1]);
    }

    client_slot.phy_cnt = serdes_cnt;

    k = 0;
    for (i = 0; i < 8; i++)
    {
        if (i >= client_slot.phy_cnt)
        {
            continue;
        }

        slot[k].serdes_id = serdes_id[i];
        CTC_BMP_INIT(slot[k].slot_bmp);

        for (j = 0; j < slot_num[i]; j++)
        {
            CTC_BMP_SET(slot[k].slot_bmp, slotlist[i][j]);
        }
        k++;
    }

    if (g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_SLOT, (void*)&client_slot);
    }
    else
    {
        ret = ctc_flexe_set_client_property(g_api_ldev, client_id, CTC_FLEXE_CLIENT_PROP_SLOT, (void*)&client_slot);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_set_client_cross,
        ctc_cli_flexe_set_client_cross_cmd,
        "flexe cross-connect client CLIENT_ID CLIENT_ID1 (enable|disable)",
        CTC_CLI_FLEXE_M_STR,
        "Flexe cross-connect",
        "FlexE client",
        "Client id",
        "Client id1",
        CTC_CLI_ENABLE,
        CTC_CLI_DISABLE)
{
    int32 ret = 0;
    uint32 client_id = 0;
    uint32 client_id1 = 0;
    bool enable = FALSE;
    ctc_flexe_cross_t cross;

    CTC_CLI_GET_UINT32("client id", client_id, argv[0]);
    CTC_CLI_GET_UINT32("client id1", client_id1, argv[1]);

    if (0 == sal_memcmp("en", argv[2], 2))
    {
        enable = TRUE;
    }

    sal_memset(&cross, 0, sizeof(ctc_flexe_cross_t));
    cross.client_id       = client_id;
    cross.dest_client_id  = client_id1;
    cross.enable          = enable;

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_client_cross(g_api_ldev, &cross);
    }
    else
    {
        ret = ctc_flexe_set_client_cross(g_api_ldev, &cross);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_get_client_cross,
        ctc_cli_flexe_get_client_cross_cmd,
        "show flexe cross-connect client CLIENT_ID CLIENT_ID1 ",
        "Show operate",
        CTC_CLI_FLEXE_M_STR,
        "Flexe cross-connect",
        "FlexE client",
        "Client id",
        "Client id1")
{
    int32 ret = 0;
    uint32 client_id = 0;
    uint32 client_id1 = 0;
    ctc_flexe_cross_t cross;

    CTC_CLI_GET_UINT32("client id", client_id, argv[0]);
    CTC_CLI_GET_UINT32("client id1", client_id1, argv[1]);

    sal_memset(&cross, 0, sizeof(ctc_flexe_cross_t));
    cross.client_id       = client_id;
    cross.dest_client_id  = client_id1;

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_get_client_cross(g_api_ldev, &cross);
    }
    else
    {
        ret = ctc_flexe_get_client_cross(g_api_ldev, &cross);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    ctc_cli_out("Cross %s\n", cross.enable?"Enable":"Disable");

    return ret;
}

CTC_CLI(ctc_cli_flexe_group_set_property,
        ctc_cli_flexe_group_set_property_cmd,
        "flexe group GROUP_ID property (cr-timer TIMER)",
        CTC_CLI_FLEXE_M_STR,
        "FlexE group",
        "Group id",
        "FlexE property",
        "FlexE CR timer",
        "Timer value")
{
    int32 ret = 0;
    uint32 group_id = 0;
    uint32 cr_timer = 0;
    uint8 index = 0;

    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);

    index = CTC_CLI_GET_ARGC_INDEX("cr-timer");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT32("cr timer", cr_timer, argv[index + 1]);
    }

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_CR_TIMER, (void*)&cr_timer);
    }
    else
    {
        ret = ctc_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_CR_TIMER, (void*)&cr_timer);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_group_set_property_sync,
        ctc_cli_flexe_group_set_sync_msg_cmd,
        "flexe group GROUP_ID property (sync-msg VALUE)",
        CTC_CLI_FLEXE_M_STR,
        "FlexE group",
        "Group id",
        "FlexE property",
        "Synchronization messaging channel",
        "Sync value, 0:disable, 1:enable(default is enable)")
{
    int32 ret = 0;
    uint32 group_id = 0;
    uint32 sync_msg = 0;
    uint8 index = 0;

    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);

    index = CTC_CLI_GET_ARGC_INDEX("sync-msg");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT32("sync-msg", sync_msg, argv[index + 1]);
    }

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_SYNC_MSG_EN, (void*)&sync_msg);
    }
    else
    {
        ret = ctc_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_SYNC_MSG_EN, (void*)&sync_msg);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}

CTC_CLI(ctc_cli_flexe_group_set_pad,
        ctc_cli_flexe_group_set_pad_cmd,
        "flexe group GROUP_ID property (pad VALUE)",
        CTC_CLI_FLEXE_M_STR,
        "FlexE group",
        "Group id",
        "FlexE property",
        "Padding",
        "Value, 0:disable, 1:enable")
{
    int32 ret = 0;
    uint32 group_id = 0;
    uint32 padding = 0;
    uint8 index = 0;

    CTC_CLI_GET_UINT32("group_id", group_id, argv[0]);

    index = CTC_CLI_GET_ARGC_INDEX("pad");
    if (0xFF != index)
    {
        CTC_CLI_GET_UINT32("padding", padding, argv[index + 1]);
    }

    if(g_ctcs_api_en)
    {
        ret = ctcs_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_PAD_EN, (void*)&padding);
    }
    else
    {
        ret = ctc_flexe_set_group_property(g_api_ldev, group_id, CTC_FLEXE_GRP_PROP_PAD_EN, (void*)&padding);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% ret = %d, %s \n", ret, ctc_get_error_desc(ret));
        return CLI_ERROR;
    }

    return ret;
}



int32
ctc_flexe_cli_init(void)
{
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_debug_on_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_debug_off_cmd);

    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_en_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_get_en_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_create_group_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_destroy_group_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_group_number_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_group_set_phylist_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_group_set_switch_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_get_group_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_phy_number_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_add_client_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_remove_client_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_get_client_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_client_groupid_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_client_number_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_client_bind_slot_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_client_port_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_client_unport_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_client_rx_recover_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_client_cross_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_show_flexe_group_property_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_show_flexe_client_property_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_show_flexe_phy_property_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_client_rxtx_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_client_prop_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_get_client_cross_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_set_group_calendar_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_show_flexe_group_oh_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_group_set_switch_mode_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_group_set_property_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_group_set_sync_msg_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_flexe_group_set_pad_cmd);

    return CLI_SUCCESS;
}

